package com.xyht.sca_s.student_manage_system.modules.questionnaire.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.modules.questionnaire.entity.*;
import com.xyht.sca_s.student_manage_system.modules.questionnaire.entity.req.*;
import com.xyht.sca_s.student_manage_system.modules.questionnaire.entity.resp.*;
import com.xyht.sca_s.student_manage_system.modules.questionnaire.mapper.*;
import com.xyht.sca_s.student_manage_system.modules.questionnaire.service.SmsQuestionnaireService;
import com.xyht.sca_s.student_manage_system.modules.tips.utils.TipsUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.questionnaire.constant.CommonConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.questionnaire.constant.LimitOrgFlagConstant.LIMIT_ORG_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.questionnaire.constant.LimitTimeFlagConstant.LIMIT_TIME_FALSE;
import static com.xyht.sca_s.student_manage_system.modules.questionnaire.constant.LimitTimeFlagConstant.LIMIT_TIME_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.questionnaire.constant.PublishFlagConstant.PUBLISH_FLAG_CANCEL;
import static com.xyht.sca_s.student_manage_system.modules.questionnaire.constant.PublishFlagConstant.PUBLISH_FLAG_PUBLISH;
import static com.xyht.sca_s.student_manage_system.modules.questionnaire.constant.RequiredFlagConstant.REQUIRED_FLAG;
import static com.xyht.sca_s.student_manage_system.modules.questionnaire.constant.SelectionFlagConstant.SELECTED_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.questionnaire.constant.TopicTypeConstant.TOPIC_TYPE_MULTIPLE;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.AppNameConstant.APP_WEB_QUESTIONNAIRE;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.CommonConstant.TIPS_QUESTIONNAIRE_DESCRIPTION_DEAL;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.CommonConstant.TIPS_QUESTIONNAIRE_TITLE_DEAL;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.RangeTypeConstant.RANGE_TYPE_ALL;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.RangeTypeConstant.RANGE_TYPE_ORG;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.TipsCloseFlagConstant.TIPS_OPEN;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.TipsTypeConstant.TIPS_TYPE_DEAL;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.UserTypeConstant.USER_TYPE_STUDENT;

/**
 * <p>
 * 投票问卷 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-01-29
 */
@Service
public class SmsQuestionnaireServiceImpl extends ServiceImpl<SmsQuestionnaireMapper, SmsQuestionnaire> implements SmsQuestionnaireService {
    //TODO  限制用户提交次数
    @Autowired
    private SmsQuestionnaireMapper smsQuestionnaireMapper;
    @Autowired
    private SmsQuestionnaireTopicMapper smsQuestionnaireTopicMapper;
    @Autowired
    private SmsQuestionnaireTopicSettingMapper smsQuestionnaireTopicSettingMapper;
    @Autowired
    private SmsQuestionnaireOptionMapper smsQuestionnaireOptionMapper;
    @Autowired
    private SmsQuestionnaireConfirmMapper smsQuestionnaireConfirmMapper;
    @Autowired
    private SmsQuestionnaireSettingMapper smsQuestionnaireSettingMapper;
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private TipsUtil tipsUtil;

    @Override
    @Transactional
    public ResponseResult addPublishQuestionnaire(SmsQuestionnaireReq smsQuestionnaireReq, String user_id) {
        if (isNullOrEmpty(smsQuestionnaireReq.getTitle()) || isNullOrEmpty(smsQuestionnaireReq.getBackground())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsQuestionnaire smsQuestionnaire = new SmsQuestionnaire();
        BeanUtils.copyProperties(smsQuestionnaireReq, smsQuestionnaire);
        smsQuestionnaire.setIsPublish(PUBLISH_FLAG_PUBLISH);
        smsQuestionnaire.setPublishUser(user_id);
        smsQuestionnaireMapper.insert(smsQuestionnaire);
        if (isNullOrEmpty(smsQuestionnaire.getId())) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
        }

        String ques_id = smsQuestionnaire.getId();

        SmsQuestionnaireSettingReq settingReq = new SmsQuestionnaireSettingReq();

        //保存问卷设置
        if (smsQuestionnaireReq.getSetting() == null) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        } else {
            settingReq = smsQuestionnaireReq.getSetting();
            if (isNullOrEmpty(settingReq.getIsLimitOrg()) || isNullOrEmpty(settingReq.getIsLimitTime())) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
            if (isNullOrEmpty(settingReq.getAlias())) {
                settingReq.setAlias(smsQuestionnaireReq.getTitle());
            }
            if (settingReq.getIsLimitTime() == LIMIT_TIME_TRUE) {
                Date bgTime = settingReq.getLimitBeginTime();
                Date endTime = settingReq.getLimitEndTime();
                if (bgTime == null || endTime == null) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_LIMIT_TIME_ERR));
                }
            }
            if (settingReq.getIsLimitOrg() == LIMIT_ORG_TRUE) {
                if (isNullOrEmpty(settingReq.getLimitOrgList())) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_LIMIT_ORG_ERR));
                }
                List<String> orgList = settingReq.getLimitOrgList();
                if (orgList == null || orgList.size() < 1) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_LIMIT_ORG_ERR));
                }
                settingReq.setLimitOrg(orgList.toString());
            }
            SmsQuestionnaireSetting setting = new SmsQuestionnaireSetting();
            BeanUtils.copyProperties(settingReq, setting);
            setting.setQuesId(ques_id);
            smsQuestionnaireSettingMapper.insert(setting);
        }

        if (smsQuestionnaireReq.getTopicList() != null && smsQuestionnaireReq.getTopicList().size() > 0) {
            Integer topic_sort = 1;
            for (SmsQuestionnaireTopicReq topicReq : smsQuestionnaireReq.getTopicList()) {
                if (isNullOrEmpty(topicReq.getType()) || isNullOrEmpty(topicReq.getTitle())) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
                }
                if (topicReq.getTopicSetting() == null || topicReq.getTopicSetting().getIsRequired() == null) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
                }

                //保存主题
                SmsQuestionnaireTopic topic = new SmsQuestionnaireTopic();
                BeanUtils.copyProperties(topicReq, topic);
                topic.setQuesId(ques_id);
                topic.setSort(topic_sort++);
                smsQuestionnaireTopicMapper.insert(topic);
                String topic_id = topic.getId();
                if (isNullOrEmpty(topic_id)) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
                }

                //保存主题设置
                SmsQuestionnaireTopicSetting topicSetting = new SmsQuestionnaireTopicSetting();
                BeanUtils.copyProperties(topicReq.getTopicSetting(), topicSetting);
                topicSetting.setQuesId(ques_id);
                topicSetting.setTopicId(topic_id);
                smsQuestionnaireTopicSettingMapper.insert(topicSetting);

                //保存主题选项
                if (topicReq.getOptionList() == null || topicReq.getOptionList().size() < 1) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
                }
                Integer option_sort = 1;
                for (SmsQuestionnaireOptionReq optionReq : topicReq.getOptionList()) {
                    SmsQuestionnaireOption option = new SmsQuestionnaireOption();
                    BeanUtils.copyProperties(optionReq, option);
                    option.setQuesId(ques_id);
                    option.setTopicId(topic_id);
                    option.setSort(option_sort++);
                    smsQuestionnaireOptionMapper.insert(option);
                }
            }

        } else {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_TOPIC_NOT_NULL);
        }

        //发布消息通知待办
        Integer range_type = RANGE_TYPE_ALL;
        if (settingReq.getIsLimitOrg() == LIMIT_ORG_TRUE) {
            range_type = RANGE_TYPE_ORG;
        }
        tipsUtil.addTips(TIPS_QUESTIONNAIRE_TITLE_DEAL,
                TIPS_QUESTIONNAIRE_DESCRIPTION_DEAL,
                TIPS_TYPE_DEAL,
                APP_WEB_QUESTIONNAIRE,
                range_type,
                settingReq.getLimitOrg(),
                smsQuestionnaire.getId(),
                USER_TYPE_STUDENT,
                null
        );

        return CommonResult.success();
    }

    @Override
    public ResponseResult addDraftQuestionnaire() {


        return null;
    }

    @Override
    public ResponseResult updateQuestionnaire() {


        return null;
    }

    @Override
    public ResponseResult getWebQuestionnaire(String user_id, Integer pageNum, Integer pageSize, String searchStr, Integer timeoutFlag) {
        List<SmsQuestionnaireResp> questionnaireRespList = new ArrayList<>();
        List<SmsQuestionnaireConfirm> confirmList = smsQuestionnaireConfirmMapper.selectList(new QueryWrapper<SmsQuestionnaireConfirm>()
                .select("DISTINCT ques_id").lambda().eq(SmsQuestionnaireConfirm::getUserId, user_id));
        List<String> quesList = confirmList.stream().map(SmsQuestionnaireConfirm::getQuesId).collect(Collectors.toList());

        List<String> quesSettingList = getAvailableQuestionnaireListBySetting(user_id, timeoutFlag);

        if (quesSettingList.size() < 1) {
            return CommonResult.success(questionnaireRespList,0);
        }
        Page<SmsQuestionnaire> page = new Page<>(pageNum, pageSize);
        QueryWrapper<SmsQuestionnaire> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SmsQuestionnaire::getIsPublish, PUBLISH_FLAG_PUBLISH)
                .orderByDesc(SmsQuestionnaire::getCreateTime);
        if (!isNullOrEmpty(searchStr)) {
            queryWrapper.lambda()
                    .like(SmsQuestionnaire::getTitle, searchStr);
        }
        if (quesList.size() > 0) {
            queryWrapper.lambda().notIn(SmsQuestionnaire::getId, quesList);
        }
        queryWrapper.lambda().in(SmsQuestionnaire::getId, quesSettingList);
        smsQuestionnaireMapper.selectPage(page, queryWrapper);
        List<SmsQuestionnaire> questionnaireList = page.getRecords();

        questionnaireRespList = questionnaireList.stream().map(ques -> {
            SmsQuestionnaireResp resp = new SmsQuestionnaireResp();
            BeanUtils.copyProperties(ques, resp);

            SmsQuestionnaireSetting setting = smsQuestionnaireSettingMapper.selectOne(new QueryWrapper<SmsQuestionnaireSetting>()
                    .lambda().eq(SmsQuestionnaireSetting::getQuesId, ques.getId()));
            if (setting != null && setting.getIsLimitTime() == LIMIT_TIME_TRUE) {
                long nowTime = new Date().getTime();
                long bgTime = setting.getLimitBeginTime().getTime();
                long endTime = setting.getLimitEndTime().getTime();
                if (nowTime > bgTime && nowTime < endTime) {
                    resp.setIsTimeout(TIMEOUT_FALSE);
                } else {
                    resp.setIsTimeout(TIMEOUT_TRUE);
                }
            } else {
                resp.setIsTimeout(TIMEOUT_FALSE);
            }
            return resp;
        }).collect(Collectors.toList());
        int total = (int) page.getTotal();
        return CommonResult.success(questionnaireRespList,total);
    }

    private List<String> getAvailableQuestionnaireListBySetting(String user_id, Integer timeoutFlag) {
        List<String> resultQuesList = new ArrayList<>();
        List<String> limitTimeQuesList = new ArrayList<>();
//        if (!isNullOrEmpty(timeoutFlag)) {
        if (!isNullOrEmpty(timeoutFlag) && timeoutFlag == TIMEOUT_TRUE) {
            Date nowTime = new Date();
            List<SmsQuestionnaireSetting> limitTimeSetting = smsQuestionnaireSettingMapper.selectList(new QueryWrapper<SmsQuestionnaireSetting>()
                    .lambda()
                    .eq(SmsQuestionnaireSetting::getIsLimitTime, LIMIT_TIME_TRUE)
                    .le(SmsQuestionnaireSetting::getLimitEndTime, nowTime));
            limitTimeQuesList = limitTimeSetting.stream().map(SmsQuestionnaireSetting::getQuesId).collect(Collectors.toList());
        } else {
            List<SmsQuestionnaireSetting> totalList = new ArrayList<>();
            List<SmsQuestionnaireSetting> notLimitTimeSetting = smsQuestionnaireSettingMapper.selectList(new QueryWrapper<SmsQuestionnaireSetting>()
                    .lambda()
                    .eq(SmsQuestionnaireSetting::getIsLimitTime, LIMIT_TIME_FALSE));

            Date nowTime = new Date();
            List<SmsQuestionnaireSetting> limitTimeSetting = smsQuestionnaireSettingMapper.selectList(new QueryWrapper<SmsQuestionnaireSetting>()
                    .lambda()
                    .eq(SmsQuestionnaireSetting::getIsLimitTime, LIMIT_TIME_TRUE)
                    .le(SmsQuestionnaireSetting::getLimitBeginTime, nowTime)
                    .ge(SmsQuestionnaireSetting::getLimitEndTime, nowTime));

            totalList.addAll(notLimitTimeSetting);
            totalList.addAll(limitTimeSetting);
            totalList = totalList.stream().distinct().collect(Collectors.toList());

            limitTimeQuesList = totalList.stream().map(SmsQuestionnaireSetting::getQuesId).collect(Collectors.toList());
        }
//        }

        if (limitTimeQuesList.size() > 0) {
            //不显示未到时间的
//            Date nowTime = new Date();
//            List<SmsQuestionnaireSetting> limitTimeSetting = smsQuestionnaireSettingMapper.selectList(new QueryWrapper<SmsQuestionnaireSetting>()
//                    .lambda()
//                    .eq(SmsQuestionnaireSetting::getIsLimitTime, LIMIT_TIME_TRUE)
//                    .ge(SmsQuestionnaireSetting::getLimitBeginTime, nowTime));
//            List<String> notDisplayList = limitTimeSetting.stream().map(SmsQuestionnaireSetting::getQuesId).collect(Collectors.toList());

            QueryWrapper<SmsQuestionnaireSetting> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(SmsQuestionnaireSetting::getQuesId, limitTimeQuesList);
            //不显示未到时间的
//            if (notDisplayList.size() > 0) {
//                queryWrapper.lambda().notIn(SmsQuestionnaireSetting::getQuesId, notDisplayList);
//            }
            List<SmsQuestionnaireSetting> questionnaireSettingList = smsQuestionnaireSettingMapper.selectList(queryWrapper);
            resultQuesList = questionnaireSettingList.stream().map(SmsQuestionnaireSetting::getQuesId).collect(Collectors.toList());

            //与需要组织判断的问卷取交集,然后对结果问卷进行逐一判断
            if (resultQuesList.size() > 0) {
                List<SmsQuestionnaireSetting> limitOrgQuestionnaireSettingList = smsQuestionnaireSettingMapper.selectList(new QueryWrapper<SmsQuestionnaireSetting>()
                        .lambda()
                        .in(SmsQuestionnaireSetting::getQuesId, resultQuesList)
                        .eq(SmsQuestionnaireSetting::getIsLimitOrg, LIMIT_ORG_TRUE));

                List<String> userOrgList = cacheUtil.getOrgList(user_id);
                List<String> notResultQuesList = limitOrgQuestionnaireSettingList.stream().filter(limitOrgSettingFilter -> {
                    List<String> orgList = JSONObject.parseArray(limitOrgSettingFilter.getLimitOrg(), String.class);
                    List<String> resultOrgList = orgList.stream().filter(org -> {
                        List<String> resultUser = userOrgList.stream().filter(userOrg -> userOrg.equals(org)).collect(Collectors.toList());
                        if (resultUser.size() > 0) {
                            return true;
                        }
                        return false;
                    }).collect(Collectors.toList());
                    if (resultOrgList.size() > 0) {
                        return false;
                    }
                    return true;
                }).map(SmsQuestionnaireSetting::getQuesId).collect(Collectors.toList());

                resultQuesList = resultQuesList.stream().filter(finalQues -> {
                    List<String> finalResult = notResultQuesList.stream().filter(not -> not.equals(finalQues)).collect(Collectors.toList());
                    if (finalResult.size() > 0) {
                        return false;
                    }
                    return true;
                }).collect(Collectors.toList());
            }
        }
        return resultQuesList;
    }


    @Override
    public ResponseResult getWebQuestionnaireHistory(String user_id, Integer pageNum, Integer pageSize, String searchStr) {
        List<SmsQuestionnaireConfirm> confirmList = smsQuestionnaireConfirmMapper.selectList(new QueryWrapper<SmsQuestionnaireConfirm>()
                .select("DISTINCT ques_id").lambda().eq(SmsQuestionnaireConfirm::getUserId, user_id));
        List<String> quesList = confirmList.stream().map(SmsQuestionnaireConfirm::getQuesId).collect(Collectors.toList());

        Page<SmsQuestionnaire> page = new Page<>(pageNum, pageSize);
        QueryWrapper<SmsQuestionnaire> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SmsQuestionnaire::getIsPublish, PUBLISH_FLAG_PUBLISH);

        List<SmsQuestionnaireResp> questionnaireRespList = new ArrayList<>();
        int total = 0;
        if (quesList.size() > 0) {
            queryWrapper.lambda()
                    .in(SmsQuestionnaire::getId, quesList);
            if (!isNullOrEmpty(searchStr)) {
                queryWrapper.lambda()
                        .like(SmsQuestionnaire::getTitle, searchStr);
            }
            smsQuestionnaireMapper.selectPage(page, queryWrapper);
            List<SmsQuestionnaire> questionnaireList = page.getRecords();

            questionnaireRespList = questionnaireList.stream().map(ques -> {
                SmsQuestionnaireResp resp = new SmsQuestionnaireResp();
                BeanUtils.copyProperties(ques, resp);
                return resp;
            }).collect(Collectors.toList());
            total = (int) page.getTotal();
        }
        return CommonResult.success(questionnaireRespList,total);
    }

    @Override
    public ResponseResult getIncompleteQuestionnaireDetail(String ques_id, String user_id) {
        if (isNullOrEmpty(ques_id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        if (!isObtainQuestionnaire(ques_id, user_id)) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_NOT_EXIST_OR_OVERTIME);
        }

        List<SmsQuestionnaireConfirm> confirmList = smsQuestionnaireConfirmMapper.selectList(new QueryWrapper<SmsQuestionnaireConfirm>()
                .lambda()
                .eq(SmsQuestionnaireConfirm::getQuesId, ques_id)
                .eq(SmsQuestionnaireConfirm::getUserId, user_id));
        if (confirmList != null && confirmList.size() > 0) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_HAD_SUBMIT);
        }

        SmsQuestionnaire questionnaire = smsQuestionnaireMapper.selectOne(new QueryWrapper<SmsQuestionnaire>()
                .lambda()
                .eq(SmsQuestionnaire::getId, ques_id)
                .eq(SmsQuestionnaire::getIsPublish, PUBLISH_FLAG_PUBLISH));
        if (questionnaire == null) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_NOT_EXIST);
        }
        SmsQuestionnaireDetailResp questionnaireDetailResp = new SmsQuestionnaireDetailResp();
        BeanUtils.copyProperties(questionnaire, questionnaireDetailResp);

        List<SmsQuestionnaireTopic> topicList = smsQuestionnaireTopicMapper.selectList(new QueryWrapper<SmsQuestionnaireTopic>()
                .lambda()
                .eq(SmsQuestionnaireTopic::getQuesId, ques_id)
                .orderByAsc(SmsQuestionnaireTopic::getSort));
        if (topicList.size() < 1) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_ERR);
        }
        List<SmsQuestionnaireTopicResp> topicRespList = topicList.stream().map(topic -> {
            SmsQuestionnaireTopicResp topicResp = new SmsQuestionnaireTopicResp();
            BeanUtils.copyProperties(topic, topicResp);

            //获取选项
            List<SmsQuestionnaireOption> optionList = smsQuestionnaireOptionMapper.selectList(new QueryWrapper<SmsQuestionnaireOption>()
                    .lambda()
                    .eq(SmsQuestionnaireOption::getTopicId, topic.getId())
                    .orderByAsc(SmsQuestionnaireOption::getSort));
            List<SmsQuestionnaireOptionResp> optionRespList = optionList.stream().map(opt -> {
                SmsQuestionnaireOptionResp optionResp = new SmsQuestionnaireOptionResp();
                BeanUtils.copyProperties(opt, optionResp);
                return optionResp;
            }).collect(Collectors.toList());
            topicResp.setOptionList(optionRespList);

            //获取设置
            SmsQuestionnaireTopicSetting smsQuestionnaireTopicSetting = smsQuestionnaireTopicSettingMapper.selectOne(new QueryWrapper<SmsQuestionnaireTopicSetting>()
                    .lambda()
                    .eq(SmsQuestionnaireTopicSetting::getTopicId, topic.getId()));
            SmsQuestionnaireTopicSettingResp topicSettingResp = new SmsQuestionnaireTopicSettingResp();
            BeanUtils.copyProperties(smsQuestionnaireTopicSetting, topicSettingResp);
            topicResp.setTopicSetting(topicSettingResp);

            return topicResp;
        }).collect(Collectors.toList());
        questionnaireDetailResp.setTopicList(topicRespList);
        return CommonResult.success(questionnaireDetailResp);
    }

    @Override
    public ResponseResult getCompleteQuestionnaireDetail(String ques_id, String user_id) {
        if (isNullOrEmpty(ques_id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsQuestionnaire questionnaire = smsQuestionnaireMapper.selectOne(new QueryWrapper<SmsQuestionnaire>()
                .lambda()
                .eq(SmsQuestionnaire::getId, ques_id)
                .eq(SmsQuestionnaire::getIsPublish, PUBLISH_FLAG_PUBLISH));
        if (questionnaire == null) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_NOT_EXIST);
        }

        SmsQuestionnaireDetailCompleteResp questionnaireDetailResp = new SmsQuestionnaireDetailCompleteResp();
        BeanUtils.copyProperties(questionnaire, questionnaireDetailResp);

        List<SmsQuestionnaireTopic> topicList = smsQuestionnaireTopicMapper.selectList(new QueryWrapper<SmsQuestionnaireTopic>()
                .lambda()
                .eq(SmsQuestionnaireTopic::getQuesId, ques_id)
                .orderByAsc(SmsQuestionnaireTopic::getSort));
        if (topicList.size() < 1) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_ERR);
        }

        //获取用户提交问卷选项
        List<SmsQuestionnaireConfirm> confirmList = smsQuestionnaireConfirmMapper.selectList(new QueryWrapper<SmsQuestionnaireConfirm>()
                .lambda()
                .eq(SmsQuestionnaireConfirm::getUserId, user_id)
                .eq(SmsQuestionnaireConfirm::getQuesId, ques_id));
        if (confirmList == null || confirmList.size() < 1) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_SUBMIT_NOT_EXIST);
        }


        List<SmsQuestionnaireTopicCompleteResp> topicRespList = topicList.stream().map(topic -> {
            SmsQuestionnaireTopicCompleteResp topicResp = new SmsQuestionnaireTopicCompleteResp();
            BeanUtils.copyProperties(topic, topicResp);

            //获取选项
            List<SmsQuestionnaireOption> optionList = smsQuestionnaireOptionMapper.selectList(new QueryWrapper<SmsQuestionnaireOption>()
                    .lambda()
                    .eq(SmsQuestionnaireOption::getTopicId, topic.getId())
                    .orderByAsc(SmsQuestionnaireOption::getSort));
            List<SmsQuestionnaireOptionCompleteResp> optionRespList = optionList.stream().map(opt -> {
                SmsQuestionnaireOptionCompleteResp optionResp = new SmsQuestionnaireOptionCompleteResp();
                BeanUtils.copyProperties(opt, optionResp);

                List<SmsQuestionnaireConfirm> result = confirmList.stream().filter(smsQuestionnaireConfirm
                        -> smsQuestionnaireConfirm.getOptionId().equals(opt.getId())).collect(Collectors.toList());
                if (result.size() > 0) {
                    optionResp.setIsSelected(SELECTED_TRUE);
                    optionResp.setSelectionContent(result.get(0).getOptionContent());
                }
                return optionResp;
            }).collect(Collectors.toList());
            topicResp.setOptionList(optionRespList);

            //获取设置
            SmsQuestionnaireTopicSetting smsQuestionnaireTopicSetting = smsQuestionnaireTopicSettingMapper.selectOne(new QueryWrapper<SmsQuestionnaireTopicSetting>()
                    .lambda()
                    .eq(SmsQuestionnaireTopicSetting::getTopicId, topic.getId()));
            SmsQuestionnaireTopicSettingResp topicSettingResp = new SmsQuestionnaireTopicSettingResp();
            BeanUtils.copyProperties(smsQuestionnaireTopicSetting, topicSettingResp);
            topicResp.setTopicSetting(topicSettingResp);

            return topicResp;
        }).collect(Collectors.toList());
        questionnaireDetailResp.setTopicList(topicRespList);
        return CommonResult.success(questionnaireDetailResp);
    }

    @Override
    public ResponseResult getBackIncompleteQuestionnaireDetail(String ques_id) {
        if (isNullOrEmpty(ques_id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsQuestionnaire questionnaire = smsQuestionnaireMapper.selectOne(new QueryWrapper<SmsQuestionnaire>()
                .lambda()
                .eq(SmsQuestionnaire::getId, ques_id));
        if (questionnaire == null) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_NOT_EXIST);
        }
        SmsQuestionnaireDetailResp questionnaireDetailResp = new SmsQuestionnaireDetailResp();
        BeanUtils.copyProperties(questionnaire, questionnaireDetailResp);

        List<SmsQuestionnaireTopic> topicList = smsQuestionnaireTopicMapper.selectList(new QueryWrapper<SmsQuestionnaireTopic>()
                .lambda()
                .eq(SmsQuestionnaireTopic::getQuesId, ques_id)
                .orderByAsc(SmsQuestionnaireTopic::getSort));
        if (topicList.size() < 1) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_ERR);
        }
        List<SmsQuestionnaireTopicResp> topicRespList = topicList.stream().map(topic -> {
            SmsQuestionnaireTopicResp topicResp = new SmsQuestionnaireTopicResp();
            BeanUtils.copyProperties(topic, topicResp);

            //获取选项
            List<SmsQuestionnaireOption> optionList = smsQuestionnaireOptionMapper.selectList(new QueryWrapper<SmsQuestionnaireOption>()
                    .lambda()
                    .eq(SmsQuestionnaireOption::getTopicId, topic.getId())
                    .orderByAsc(SmsQuestionnaireOption::getSort));
            List<SmsQuestionnaireOptionResp> optionRespList = optionList.stream().map(opt -> {
                SmsQuestionnaireOptionResp optionResp = new SmsQuestionnaireOptionResp();
                BeanUtils.copyProperties(opt, optionResp);
                return optionResp;
            }).collect(Collectors.toList());
            topicResp.setOptionList(optionRespList);

            //获取设置
            SmsQuestionnaireTopicSetting smsQuestionnaireTopicSetting = smsQuestionnaireTopicSettingMapper.selectOne(new QueryWrapper<SmsQuestionnaireTopicSetting>()
                    .lambda()
                    .eq(SmsQuestionnaireTopicSetting::getTopicId, topic.getId()));
            SmsQuestionnaireTopicSettingResp topicSettingResp = new SmsQuestionnaireTopicSettingResp();
            BeanUtils.copyProperties(smsQuestionnaireTopicSetting, topicSettingResp);
            topicResp.setTopicSetting(topicSettingResp);

            return topicResp;
        }).collect(Collectors.toList());
        questionnaireDetailResp.setTopicList(topicRespList);
        return CommonResult.success(questionnaireDetailResp);
    }

    @Override
    public ResponseResult getBackCompleteQuestionnaireDetail(String ques_id, String user_id) {
        if (isNullOrEmpty(ques_id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsQuestionnaire questionnaire = smsQuestionnaireMapper.selectOne(new QueryWrapper<SmsQuestionnaire>()
                .lambda()
                .eq(SmsQuestionnaire::getId, ques_id));
        if (questionnaire == null) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_NOT_EXIST);
        }

        SmsQuestionnaireDetailCompleteResp questionnaireDetailResp = new SmsQuestionnaireDetailCompleteResp();
        BeanUtils.copyProperties(questionnaire, questionnaireDetailResp);

        List<SmsQuestionnaireTopic> topicList = smsQuestionnaireTopicMapper.selectList(new QueryWrapper<SmsQuestionnaireTopic>()
                .lambda()
                .eq(SmsQuestionnaireTopic::getQuesId, ques_id)
                .orderByAsc(SmsQuestionnaireTopic::getSort));
        if (topicList.size() < 1) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_ERR);
        }

        //获取用户提交问卷选项
        List<SmsQuestionnaireConfirm> confirmList = smsQuestionnaireConfirmMapper.selectList(new QueryWrapper<SmsQuestionnaireConfirm>()
                .lambda()
                .eq(SmsQuestionnaireConfirm::getUserId, user_id)
                .eq(SmsQuestionnaireConfirm::getQuesId, ques_id));
        if (confirmList == null || confirmList.size() < 1) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_SUBMIT_USER_NOT_EXIST);
        }

        List<SmsQuestionnaireTopicCompleteResp> topicRespList = topicList.stream().map(topic -> {
            SmsQuestionnaireTopicCompleteResp topicResp = new SmsQuestionnaireTopicCompleteResp();
            BeanUtils.copyProperties(topic, topicResp);

            //获取选项
            List<SmsQuestionnaireOption> optionList = smsQuestionnaireOptionMapper.selectList(new QueryWrapper<SmsQuestionnaireOption>()
                    .lambda()
                    .eq(SmsQuestionnaireOption::getTopicId, topic.getId())
                    .orderByAsc(SmsQuestionnaireOption::getSort));
            List<SmsQuestionnaireOptionCompleteResp> optionRespList = optionList.stream().map(opt -> {
                SmsQuestionnaireOptionCompleteResp optionResp = new SmsQuestionnaireOptionCompleteResp();
                BeanUtils.copyProperties(opt, optionResp);

                List<SmsQuestionnaireConfirm> result = confirmList.stream().filter(smsQuestionnaireConfirm
                        -> smsQuestionnaireConfirm.getOptionId().equals(opt.getId())).collect(Collectors.toList());
                if (result.size() > 0) {
                    optionResp.setIsSelected(SELECTED_TRUE);
                    optionResp.setSelectionContent(result.get(0).getOptionContent());
                }
                return optionResp;
            }).collect(Collectors.toList());
            topicResp.setOptionList(optionRespList);

            //获取设置
            SmsQuestionnaireTopicSetting smsQuestionnaireTopicSetting = smsQuestionnaireTopicSettingMapper.selectOne(new QueryWrapper<SmsQuestionnaireTopicSetting>()
                    .lambda()
                    .eq(SmsQuestionnaireTopicSetting::getTopicId, topic.getId()));
            SmsQuestionnaireTopicSettingResp topicSettingResp = new SmsQuestionnaireTopicSettingResp();
            BeanUtils.copyProperties(smsQuestionnaireTopicSetting, topicSettingResp);
            topicResp.setTopicSetting(topicSettingResp);

            return topicResp;
        }).collect(Collectors.toList());
        questionnaireDetailResp.setTopicList(topicRespList);
        return CommonResult.success(questionnaireDetailResp);
    }

    @Override
    public ResponseResult getBackQuestionnaire(String user_id, Integer pageNum, Integer pageSize) {
        Page<SmsQuestionnaire> page = new Page<>(pageNum, pageSize);
        QueryWrapper<SmsQuestionnaire> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SmsQuestionnaire::getPublishUser, user_id)
                .orderByDesc(SmsQuestionnaire::getCreateTime);
        smsQuestionnaireMapper.selectPage(page, queryWrapper);
        List<SmsQuestionnaire> questionnaireList = page.getRecords();

        List<SmsQuestionnaireResp> questionnaireRespList = questionnaireList.stream().map(ques -> {
            SmsQuestionnaireResp resp = new SmsQuestionnaireResp();
            BeanUtils.copyProperties(ques, resp);

            SmsQuestionnaireSetting setting = smsQuestionnaireSettingMapper.selectOne(new QueryWrapper<SmsQuestionnaireSetting>()
                    .lambda().eq(SmsQuestionnaireSetting::getQuesId, ques.getId()));
            if (setting != null && setting.getIsLimitTime() == LIMIT_TIME_TRUE) {
                long nowTime = new Date().getTime();
                long bgTime = setting.getLimitBeginTime().getTime();
                long endTime = setting.getLimitEndTime().getTime();
                if (nowTime > bgTime && nowTime < endTime) {
                    resp.setIsTimeout(TIMEOUT_FALSE);
                } else {
                    resp.setIsTimeout(TIMEOUT_TRUE);
                }
            } else {
                resp.setIsTimeout(TIMEOUT_FALSE);
            }
            return resp;
        }).collect(Collectors.toList());
        int total = (int) page.getTotal();
        return CommonResult.success(questionnaireRespList,total);
    }

    @Override
    public ResponseResult getBackQuestionnaireCancel(String ques_id, String user_id) {
        if (isNullOrEmpty(ques_id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsQuestionnaire questionnaire = smsQuestionnaireMapper.selectById(ques_id);
        if (questionnaire == null) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_NOT_EXIST);
        }
        if (!questionnaire.getPublishUser().equals(user_id)) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_NOT_OWN);
        }
        SmsQuestionnaire smsQuestionnaire = new SmsQuestionnaire();
        smsQuestionnaire.setId(ques_id);
        smsQuestionnaire.setIsPublish(PUBLISH_FLAG_CANCEL);
        smsQuestionnaireMapper.updateById(smsQuestionnaire);

        //消息待办取消
        tipsUtil.closeTips(ques_id);

        return CommonResult.success();
    }

    @Override
    public ResponseResult getBackQuestionnaireSubmitList(String user_id, Integer pageNum, Integer pageSize) {
        return null;
    }


    @Override
    @Transactional
    public ResponseResult submitQuestionnaire(SmsQuestionnaireConfirmReq questionnaireConfirmReq, String user_id) {
        if (isNullOrEmpty(questionnaireConfirmReq.getQuesId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        if (!isObtainQuestionnaire(questionnaireConfirmReq.getQuesId(), user_id)) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_NOT_EXIST_OR_OVERTIME);
        }

        if (questionnaireConfirmReq.getTopicList() == null || questionnaireConfirmReq.getTopicList().size() < 1) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsQuestionnaire questionnaire = smsQuestionnaireMapper.selectById(questionnaireConfirmReq.getQuesId());
        if (questionnaire == null || questionnaire.getIsPublish() != PUBLISH_FLAG_PUBLISH) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_NOT_EXIST);
        }

        List<SmsQuestionnaireConfirm> confirmList = smsQuestionnaireConfirmMapper.selectList(new QueryWrapper<SmsQuestionnaireConfirm>()
                .lambda()
                .eq(SmsQuestionnaireConfirm::getUserId, user_id)
                .eq(SmsQuestionnaireConfirm::getQuesId, questionnaireConfirmReq.getQuesId()));
        if (confirmList != null && confirmList.size() > 0) {
            return CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_SUBMIT_LIMIT);
        }

        for (SmsQuestionnaireConfirmTopicReq topicReq : questionnaireConfirmReq.getTopicList()) {
            if (isNullOrEmpty(topicReq.getTopicId()) || topicReq.getOptionList() == null) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
            }
            SmsQuestionnaireTopicSetting topicSetting = smsQuestionnaireTopicSettingMapper.selectOne(new QueryWrapper<SmsQuestionnaireTopicSetting>()
                    .lambda().eq(SmsQuestionnaireTopicSetting::getTopicId, topicReq.getTopicId()));
            if (topicSetting.getIsRequired() == REQUIRED_FLAG && topicReq.getOptionList().size() < 1) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_REQUIRED_NOT_FILL));
            }
            SmsQuestionnaireTopic topic = smsQuestionnaireTopicMapper.selectById(topicSetting.getTopicId());
            if (topic == null) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
            }
            if (!topic.getType().equals(TOPIC_TYPE_MULTIPLE) && topicReq.getOptionList().size() > 1) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_OPTION_LIMIT_ERR));
            }

            if (topicReq.getOptionList().size() > 0) {
                if (topic.getType().equals(TOPIC_TYPE_MULTIPLE)) {
                    if (topicSetting.getOptionLeast() != OPTION_NUM_NOT_LIMIT
                            && topicReq.getOptionList().size() < topicSetting.getOptionLeast()) {
                        ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_OPTION_LIMIT_ERR));
                    }
                    if (topicSetting.getOptionLeast() != OPTION_NUM_NOT_LIMIT
                            && topicReq.getOptionList().size() > topicSetting.getOptionMost()) {
                        ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.QUESTIONNAIRE_OPTION_LIMIT_ERR));
                    }
                }

                for (SmsQuestionnaireConfirmOptionReq optionReq : topicReq.getOptionList()) {
                    SmsQuestionnaireConfirm questionnaireConfirm = new SmsQuestionnaireConfirm();
                    questionnaireConfirm.setOptionId(optionReq.getOptionId());
                    questionnaireConfirm.setOptionContent(optionReq.getOptionContent());
                    questionnaireConfirm.setUserId(user_id);
                    questionnaireConfirm.setQuesId(questionnaireConfirmReq.getQuesId());
                    questionnaireConfirm.setTopicId(topicReq.getTopicId());

                    smsQuestionnaireConfirmMapper.insert(questionnaireConfirm);
                }
            }
        }

        //消息待办完成
        tipsUtil.finishTips(questionnaireConfirmReq.getQuesId(), user_id,TIPS_OPEN);

        return CommonResult.success();
    }

    private boolean isObtainQuestionnaire(String ques_id, String user_id) {
        SmsQuestionnaire questionnaire = smsQuestionnaireMapper.selectById(ques_id);
        if (questionnaire == null) {
            return false;
        }
        SmsQuestionnaireSetting setting = smsQuestionnaireSettingMapper.selectOne(new QueryWrapper<SmsQuestionnaireSetting>()
                .lambda()
                .eq(SmsQuestionnaireSetting::getQuesId, ques_id));
        if (setting == null) {
            return false;
        }
        if (setting.getIsLimitTime() == LIMIT_TIME_TRUE) {
            long bgTime = setting.getLimitBeginTime().getTime();
            long endTime = setting.getLimitEndTime().getTime();
            long nowTime = new Date().getTime();

            if (nowTime < bgTime || nowTime > endTime) {
                return false;
            }
        }

        if (setting.getIsLimitOrg() == LIMIT_ORG_TRUE) {
            List<String> userOrgList = cacheUtil.getOrgList(user_id);
            List<String> limitOrgList = JSONObject.parseArray(setting.getLimitOrg(), String.class);
            List<String> filterList = limitOrgList.stream().filter(limitOrg -> {
                List<String> result = userOrgList.stream().filter(org -> org.equals(limitOrg)).collect(Collectors.toList());
                if (result.size() > 0) {
                    return true;
                }
                return false;
            }).collect(Collectors.toList());
            if (filterList.size() < 1) {
                return false;
            }
        }
        return true;
    }


}
